﻿using DBServer.Selenium.Extenium.Exception;
using DBServer.Selenium.Extenium.Path;
using Selenium;

namespace DBServer.Selenium.Extenium.Fixtures
{
    public abstract class TextFieldFixture<T> : ExtComponentFixture where T : TextFieldFixture<T>
    {
        private readonly IPath _path;

        protected TextFieldFixture(ISelenium driver, IPath path)
            : base(driver, path)
        {
            _path = path;
        }

        /*public virtual T SetText(string text)
        {
            SafeExec(_path.Eval() + ".setValue('" + text + "');");
            return (T) this;
        }*/

        public virtual T TypeText(string text)
        {
            /*Driver.Type("id=" + ((ExtComponentPath)_path).Id(), text);*/
            Wait(() => SafeExec(_path.Eval() + ".getValue();") == "");
            Driver.TypeKeys("id=" + ((ExtComponentPath)_path).Id(), text);
            
            return (T)this;
        }

        public virtual T SetText(string text)
        {
            Wait(() => SafeExec(_path.Eval() + ".getValue();") == "");
            Driver.Type("id=" + ((ExtComponentPath)_path).Id(), text);
            return (T) this;
        }

        public virtual T RequireText(string text)
        {
            Wait(() => SafeExec(_path.Eval() + ".getValue();") == text);
            var value = SafeExec(_path.Eval() + ".getValue();");
            if (value != text)
            {
                throw new ExteniumException("Unexpected text: " + value + " (expected: " + text + ")");
            }
            return (T) this;
        }

        public virtual T RequireTextNotEmpty()
        {
            var value = SafeExec(_path.Eval() + ".getValue();");
            if (string.IsNullOrEmpty(value))
            {
                throw new ExteniumException("Unexpected empty field.(Expected: not empty string)");
            }
            return (T)this;
        }

        public virtual T RequireDiferentText(string text)
        {
            Wait(() => SafeExec(_path.Eval() + ".getValue();") == text);
            var value = SafeExec(_path.Eval() + ".getValue();");
            if (value == text)
            {
                throw new ExteniumException("Unexpected text: " + value + " (expected not equals)");
            }
            return (T)this;
        }

        public virtual T RequireReadOnly()
        {
            var value = bool.Parse(SafeExec(_path.Eval() + ".readOnly;"));
            if (!value)
            {
                throw new ExteniumException("Component should be read-only");
            }
            return (T) this;
        }

        public virtual T RequireReadWrite()
        {
            var value = bool.Parse(SafeExec(_path.Eval() + ".readOnly;"));
            if (value)
            {
                throw new ExteniumException("Component should be read-write");
            }
            return (T) this;
        }

        public virtual T RequireValidContent()
        {
            var value = bool.Parse(SafeExec(_path.Eval() + ".isValid();"));
            if (!value)
            {
                throw new ExteniumException("Content should be considered valid");
            }
            return (T) this;
        }

        public virtual T RequireInvalidContent()
        {
            var value = bool.Parse(SafeExec(_path.Eval() + ".isValid();"));
            if (value)
            {
                throw new ExteniumException("Content should be considered invalid");
            }
            return (T) this;
        }
    }

    public class TextFieldFixture : TextFieldFixture<TextFieldFixture>
    {
        public TextFieldFixture(ISelenium driver, IPath path) : base(driver, path) { }
    }
}